void lex_analyse(){
	do{//循环执行，直到文件位置标识符抵达文件尾
		switch(state){
			case 0://初始状态，根据下一个字符，决定跳转的状态（每个状态都是如此）
				token="";//将字串清空 //TODO 参考书本的名称
				c=fgetc(fpin); //输入下一个字符，并将文件位置符后移
				if(int(c)==-1){//跳过空格
					get_nbc();
				}
				
				if(isLetter(c)||c=='_'){//判断标识符/关键字开头
					state= 1;
					break;
				}	
				else if(isDigit(c)) { //判断常数开头
					state= 2;
					break;
				}
				else if(cm[c]!=""){//判断简单符号
					fout << cm[c] << " " << c<< endl;//简单符号可直接判断，将判断结果写入输出。	
					state= 0;//返回初始状态
					break;
				}
				else{//判断复合符号
					switch(c){
						case '<': 
							state=3;
							break;
						case '>': 
							state=4;
							break;
						case '=':  
							state=5;
							break;
						case '!': 
							state=6;
							break;
						case '\'': //字符串常量
							state=7;
							break;
						case '"': //字符串
							state=8;
							break;
						default: 
							break;					
					}
				}
				break;
			case 1: //识别标识符和关键字
				token+=c;//将当前字符加入正在识别的字符串
				c=fgetc(fpin);//读入下一个字符，并移动文件位置指示符
				if(isDigit(c)||isLetter(c)||c=='_'){//除开头外，标识符可以由字母、数字、下划线组成。输入其他符号说明标识符已结束
					state= 1;
					break;
				}
				else{//下一个字符与标识符无关，标识符到此为止。进一步排除区别关键字/标识符
					fseek(fpin, -1, SEEK_CUR);// 文件位置符后退一位，消除fgetc的影响，使得新的字符能够在初始状态被重新处理。需用fseek操作FILE对象的文件位置符
					state=0;
					if(keylookup(token)!=""){ //写入关键字
						fout << keylookup(token) << " " << token << endl;

					}else{//写入标识符
						fout << "IDENFR " << token << endl;
					}
				}
				break;
			case 2://识别整数常数
				token+=c;
				c=fgetc(fpin);
				if(isDigit(c)){//输入非数字说明数字已结束
					state= 2;
					break;
				}
				else{ //下一个字符与整数常量无关，整数常量到此为止。
					fseek(fpin, -1, SEEK_CUR);
					state= 0;
					fout << "INTCON " << token << endl;//写入整数常量
				}
				break;
			case 3://小于号 
				token+=c;
				c=fgetc(fpin);
				if(c=='='){//下一个字符为等号，识别为LEQ
					token+=c;//将等号插入当前识别的字符串，以便输出
					fout << "LEQ " << token << endl;
					state= 0;//当前字符串识别完毕，接下来回到初始状态
					break;
				}
				else{//下一个不为等号，识别为LSS
					fseek(fpin, -1, SEEK_CUR);//位置符回退
					state= 0;//接下来返回初始状态
					fout << "LSS " << token << endl;
					break;
				}
				break;
			case 4://大于号
				token+=c;
				c=fgetc(fpin);
				if(c=='='){//下一个字符为等号，识别为GEQ
					token+=c;
					fout << "GEQ " << token << endl;
					state= 0;
					break;
				}
				else{//下一个不为等号，识别为GRE
					fseek(fpin, -1, SEEK_CUR);
					state= 0;
					fout << "GRE " << token << endl;
					break;
				}
				break;
			case 5://等号
				token+=c;
				c=fgetc(fpin);
				if(c=='='){//下一个字符为等号，识别为EQL
					token+=c;
					fout << "EQL " << token << endl;
					state= 0;
					break;
				}
				else{//下一个字符不为等号，识别为ASSIGN
					fseek(fpin, -1, SEEK_CUR);
					state= 0;
					fout << "ASSIGN " << token << endl;
					break;
				}
				break;
			case 6://感叹号!
				token+=c;
				c=fgetc(fpin);
				if(c=='='){//下一个字符为=，识别为NEQ
					token+=c;
					fout << "NEQ " << token << endl;
					break;
				}
				else{//下一个字符不为=，出错
					fseek(fpin, -1, SEEK_CUR);
					state= 0;
					error(c);
					break;
				}
				break;
			case 7://单引号'(字符常量的左引号)
				c=fgetc(fpin);
				if(c=='\''){//下一个字符为'，即字符常量的右引号，字符常量结束  //TODO 字符常量为空应报错
					fout << "CHARCON " << token << endl;
					state=0;
					break;
				}
				else{//下一个字符不为'，读入的是字符常量的字符，直到读入第二个单引号才结束
					token+=c;
					state= 7;
					break;
				}
				break;
			case 8://单引号" (字符串的左引号)
				c=fgetc(fpin);
				if(c=='"'){//下一个字符为"，即字符串的右引号，字符串结束  //TODO 字符串为空应报错
					fout << "STRCON " << token << endl;
					state=0;
					break;
				}
				else{//下一个字符不为"，读入的是字符串的字符，直到读入第二个双引号才结束
					token+=c;
					state= 8;
					break;
				}
				break;
			default://状态不存在，输出错误
				fout << "NO CASE ERROR"<< endl;
				return;
				break;
		}
	}while(ftell(fpin)!=filesize);
}